package com.subfg.common.util.network;

import com.ip2location.IP2Location;
import com.ip2location.IPResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;

public class IP2LocUtils {
    private static final Logger logger = LoggerFactory.getLogger(IP2LocUtils.class);

    public static IP2Location ipDatabase;

    static {
        ipDatabase = new IP2Location();
        try {
            ClassPathResource resource = new ClassPathResource(
                    "IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ISP-DOMAIN-MOBILE.BIN");
            ipDatabase.Open(resource.getFile().getAbsolutePath(), true);
        } catch (IOException e) {
            logger.error("加载ip2location bin文件失败");
        }
    }

    public static void reloadIp2Loc() {
        ipDatabase = new IP2Location();
        try {
            ClassPathResource resource = new ClassPathResource(
                    "IP-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ISP-DOMAIN-MOBILE.BIN");
            ipDatabase.Open(resource.getFile().getAbsolutePath(), true);
        } catch (IOException e) {
            logger.error("reload ip2location bin文件失败");
        }
    }

    public static String getCountryName(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                result = ipQuery.getCountryLong();
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String getCountryCode(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                String countryCode = ipQuery.getCountryShort();
                if(!"-".equals(countryCode)) {
                    result = countryCode.toLowerCase();
                }
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String getCity(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                result = ipQuery.getCity();
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String getISP(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                result = ipQuery.getISP();
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String getTelcoName(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                result = ipQuery.getMobileBrand();
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String getTelcoCode(String ip) {
        String result = null;
        try {
            IPResult ipQuery = ipQuery(ip);
            if(ipQuery != null) {
                String mcc = ipQuery.getMCC();
                String mnc = ipQuery.getMNC();
                if(!"-".equals(mcc) && !"-".equals(mnc)) {
                    if(mnc.contains("/")) {
                        result = mcc + mnc.substring(0,mnc.indexOf("/"));
                    }else {
                        result = mcc + mnc;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static IPResult ipQuery(String ip) {
        IPResult result = null;
        try {
            IPResult rec = ipDatabase.IPQuery(ip);
            if ("OK".equals(rec.getStatus())) {
                result = rec;
            } else if ("EMPTY_IP_ADDRESS".equals(rec.getStatus())) {
                throw new RuntimeException("IP address cannot be blank.");
            } else if ("INVALID_IP_ADDRESS".equals(rec.getStatus())) {
                throw new RuntimeException("Invalid IP address.");
            } else if ("MISSING_FILE".equals(rec.getStatus())) {
                throw new RuntimeException("Invalid database path.");
            } else if ("IPV6_NOT_SUPPORTED".equals(rec.getStatus())) {
                throw new RuntimeException("This BIN does not contain IPv6 data.");
            } else {
                throw new RuntimeException("Unknown error." + rec.getStatus());
            }
        } catch (Exception e) {
            logger.error("",e);
        }
        return result;
    }

    public static String ipQueryCountry(String ip){
        if (ip.equals("127.0.0.1")) {
            return "本机";
        }
        StringBuilder country = new StringBuilder();
        try {
            IPResult rec = ipDatabase.IPQuery(ip);
            if ("OK".equals(rec.getStatus())) {
                country.append(rec.getCountryShort());
                country.append("-"+rec.getRegion());
                country.append("("+rec.getCity()+")");
            } else if ("EMPTY_IP_ADDRESS".equals(rec.getStatus())) {
                country = new StringBuilder("Unknown Address 1");
            } else if ("INVALID_IP_ADDRESS".equals(rec.getStatus())) {
                country = new StringBuilder("Unknown Address 2");
            } else if ("MISSING_FILE".equals(rec.getStatus())) {
                country = new StringBuilder("Unknown Address 3");
            } else if ("IPV6_NOT_SUPPORTED".equals(rec.getStatus())) {
                country = new StringBuilder("Unknown Address 4");
            } else {
                country = new StringBuilder("Unknown Address 5");
            }
        } catch (Exception e) {
            logger.error("",e);
            country = new StringBuilder("Unknown Address 5");
        }
        if("---(-)".equals(country.toString())){
            country = new StringBuilder("Unknown Address 6");
        }
        return country.toString();
    }
}
